<template>

  <el-card class="box-card" style="position:relative">

    <el-form label-width="100px" class="fromClass" :model="articleForm" :rules="articleFromRules" ref="articleForm">

      <div style="border: 1px solid #ccc;">
        <el-form-item id="form-item-content" label-width="0px" prop="content">
          <!--  工具栏  -->
          <Toolbar style="border-bottom: 1px solid #ccc;" :editor="editor" :defaultConfig="toolbarConfig"
            :mode="mode" />

          <!-- 编辑器 -->
          <Editor style="height: 500px; overflow-y: hidden;" v-model="articleForm.content" :defaultConfig="editorConfig"
            :mode="mode" @onCreated="onCreated" />
        </el-form-item>
      </div>

      <!-- 其它内容 -->
      <div class="d1">
        <el-form-item label="文章标题" prop="title">
          <el-input v-model="articleForm.title"></el-input>
        </el-form-item>

        <el-form-item label="文章简介" prop="intro">
          <el-input class="text" :rows="4" style="width: 400px" type="textarea" v-model="articleForm.intro"></el-input>
        </el-form-item>

        <el-form-item label="上传封面" prop="cover">
          <my-upload-img ref="upload" url="/articles/cover/photo" @upload-success="handleUploadSuccess"
            :imageUrl="articleForm.cover" />
        </el-form-item>

        <el-form-item label="文章类型" prop="type">
          <el-radio-group v-model="articleForm.type">
            <el-radio :label="1">原创</el-radio>
            <el-radio :label="2">转载</el-radio>
            <el-radio :label="3">翻译</el-radio>
          </el-radio-group>
        </el-form-item>

        <div v-if="articleForm.type === 2">
          <!-- 转载 -->
          <el-form-item label="原作者" prop="author">
            <el-input v-model="articleForm.author"></el-input>
          </el-form-item>

          <el-form-item label="原文链接" prop="url">
            <el-input v-model="articleForm.originalUrl"></el-input>
          </el-form-item>
        </div>

        <div v-if="articleForm.type === 3">
          <!-- 翻译 -->
          <el-form-item label="原作者" prop="author">
            <el-input v-model="articleForm.author"></el-input>
          </el-form-item>

          <el-form-item label="原文链接" prop="url">
            <el-input v-model="articleForm.originalUrl"></el-input>
          </el-form-item>
        </div>

        <el-form-item label="状态" prop="type">
          <el-radio-group v-model="articleForm.status">
            <el-radio :label="0">公开</el-radio>
            <el-radio :label="1">私密</el-radio>
            <el-radio :label="2">草稿</el-radio>
          </el-radio-group>
        </el-form-item>

        <el-form-item label="文章分类" prop="categoryId">
          <my-select v-model="articleForm.categoryId" placeholder="请选择分类" :showList="categoryList"
            labelName='categoryName' valueName='id' />
        </el-form-item>

        <el-form-item label="文章标签" prop="tagId">
          <el-tag v-for="item of articleForm.tagVOList" :key="item.tagId" closable @close="closeTag(item)"
            :disable-transitions="true" style="margin-right:0.2rem;margin-top:0.2rem">
            {{ item.tagName }}
          </el-tag>

          <el-button type="info" plain size="mini" icon="el-icon-plus" @click="openTagDialog">
            添加标签
          </el-button>
        </el-form-item>
      </div>

      <!-- 按钮区域 -->
      <div class="but">
        <el-form-item class="from-item-but">
          <el-button id="subButton" type="primary" @click="uaArticles('articleForm')">提交</el-button>
          <el-button id="subButton" type="warning" @click="resetForm('articleForm')">重置</el-button>
          <el-button id="subButton" type="danger" @click="cancel">取消</el-button>
        </el-form-item>
      </div>
    </el-form>


    <!--  添加标签  -->
    <el-dialog title="添加标签" :visible.sync="tagDialog" width="40%" :before-close="closeTagDialog">
      <el-button v-for="item of tagList" :key="item.id" type="primary" size="mini"
        @click="addTag({ id: item.id, tagName: item.tagName })" style="margin-right:0.2rem;margin-top:0.2rem">
        {{ item.tagName }}
      </el-button>
    </el-dialog>


  </el-card>
</template>

<script>
//引入wangEditor
import '@wangeditor/editor/dist/css/style.css'
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";


export default {
  name: "ArticleAdd",
  components: { Editor, Toolbar },
  data() {
    /**
     * 自定义校验链接
     * @param text
     * @param url
     */
    function customCheckLinkFn(text, url) {
      if (!url) {
        return
      }
      if (url.indexOf('http') !== 0) {
        return '链接必须以 http/https 开头'
      }
      return true

      // 返回值有三种选择：
      // 1. 返回 true ，说明检查通过，编辑器将正常插入链接
      // 2. 返回一个字符串，说明检查未通过，编辑器会阻止插入。会 alert 出错误信息（即返回的字符串）
      // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止插入。但不会提示任何信息
    }

    /**
     * 自定义转换链接 url
     * @param url
     */
    function customParseLinkUrl(url) {
      if (url.indexOf('http') !== 0) {
        return `http://${url}`
      }
      return url
    }

    /**
     * 自定义校验图片
     * @param src
     * @param alt
     * @param url
     */
    function customCheckImageFn(src, alt, url) {
      if (!src) {
        return
      }
      if (src.indexOf('http') !== 0) {
        return '图片网址必须以 http/https 开头'
      }
      return true

      // 返回值有三种选择：
      // 1. 返回 true ，说明检查通过，编辑器将正常插入图片
      // 2. 返回一个字符串，说明检查未通过，编辑器会阻止插入。会 alert 出错误信息（即返回的字符串）
      // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止插入。但不会提示任何信息
    }

    /**
     * 自定义转换图片 src
     * @param src
     */
    function customParseImageSrc(src) {
      if (src.indexOf('http') !== 0) {
        return `http://${src}`
      }
      return src
    }

    const that = this
    return {
      //编辑器实例
      editor: null,
      //工具栏配置
      toolbarConfig: {},
      //编辑器配置
      editorConfig: {
        placeholder: '请输入正文内容...',
        MENU_CONF: {
          // 插入链接
          insertLink: {
            // checkLink 校验链接
            // parseLinkUrl 转换链接 url
            checkLink: customCheckLinkFn, // 也支持 async 函数
            parseLinkUrl: customParseLinkUrl, // 也支持 async 函数
          },

          // 更新链接
          editLink: {
            checkLink: customCheckLinkFn, // 也支持 async 函数
            parseLinkUrl: customParseLinkUrl, // 也支持 async 函数
          },

          // 插入图片
          insertImage: {
            // onInsertedImage 插入图片之后的回调
            // checkImage 校验图片链接
            // parseImageSrc 转换图片链接
            onInsertedImage(imageNode) {
              if (imageNode == null) return

              const { src, alt, url, href } = imageNode
              console.log('inserted image', src, alt, url, href)
            },
            checkImage: customCheckImageFn, // 也支持 async 函数
            parseImageSrc: customParseImageSrc, // 也支持 async 函数
          },

          // 更新图片
          editImage: {
            // onUpdatedImage 更新图片之后的回调
            onUpdatedImage(imageNode) {
              if (imageNode == null) return

              const { src, alt, url } = imageNode
              console.log('updated image', src, alt, url)
            },
            checkImage: customCheckImageFn, // 也支持 async 函数
            parseImageSrc: customParseImageSrc, // 也支持 async 函数
          },

          // 上传图片配置
          uploadImage: {
            // 服务端地址-必填
            server: `${process.env.VUE_APP_BASE_URL}/photo/upload`,

            // form-data fieldName ，默认值 'wangeditor-uploaded-image'
            fieldName: 'file',

            // 单个文件的最大体积限制，默认为 2M
            maxFileSize: 5 * 1024 * 1024,

            // 最多可上传几个文件，默认为 100
            maxNumberOfFiles: 10,

            // 选择文件时的类型限制，默认为 ['image/*'] 。如不想限制，则设置为 []
            allowedFileTypes: ['image/*'],

            // 自定义上传参数，例如传递验证的 token 等。参数会被添加到 formData 中，一起上传到服务端。
            // meta: {
            //   token: 'xxx',
            //   otherKey: 'yyy',
            // },

            // 将 meta 拼接到 url 参数中，默认 false
            metaWithUrl: false,

            // 自定义增加 http  header
            headers: {
              Authorization: JSON.parse(localStorage.getItem('vuex')).accessToken,
            },

            // 跨域是否传递 cookie ，默认为 false
            // withCredentials: true,

            // 超时时间，默认为 10 秒
            timeout: 5 * 1000, // 5 秒

            // 上传之前触发
            onBeforeUpload(file) {
              // file 选中的文件，格式如 { key: file }
              return file

              // 可以 return
              // 1. return file 或者 new 一个 file ，接下来将上传
              // 2. return false ，不上传这个 file
            },

            // 上传进度的回调函数
            onProgress(progress) {
              // progress 是 0-100 的数字
              console.log('progress', progress)
            },

            // 上传成功的回调函数
            onSuccess(file, res) {
              that.$message({ message: `${file.name} ${res.message}`, type: 'success' })
            },

            // 单个文件上传失败
            onFailed(file, res) {
              that.$message({ message: `${file.name} ${res.message}`, type: 'error' })
            },

            // 上传出错的回调
            onError(file, err, res) {
              that.$message({ message: `${file.name} ${res.message}`, type: 'error' })
            },

            // 自定义插入图片
            customInsert(res, insertFn) {
              // res 即服务端的返回结果
              // 从 res 中找到 url alt href ，然后插入图片
              // 这里的 url 是图片的地址（必须），alt 是图片的描述，href 是图片的链接
              // insertFn(url, alt, href)
              console.log('customInsert', res)
              insertFn(res.data, "", "")
            },
          }

        },
      },
      //编辑模式
      mode: 'default', // or 'simple'
      articleId: null,
      articleForm: {
        title: '',
        content: '',
        intro: '',
        cover: '',
        type: '',
        status: 0,
        author: '',
        originalUrl: '',
        categoryId: '',
        tagVOList: []
      },
      articleFromRules: {
        title: [
          { required: true, message: '请输入文章标题', trigger: 'blur' }
        ],
        type: [
          { required: true, message: '请选择文章类型', trigger: 'blur' }
        ],
      },
      categoryList: [],
      tagList: [],
      tagDialog: false,
    }
  },


  methods: {
    //编辑器初始化
    onCreated(editor) {
      this.editor = Object.seal(editor) // 一定要用 Object.seal() ，否则会报错
    },

    /**
     * 获取图片上传后的地址
     * @param data
     */
    handleUploadSuccess(data) {
      this.articleForm.cover = data.data;
    },

    // 重置表单内容
    resetForm(formName) {
      this.$refs.articleForm.resetFields();
      this.articleForm = {}
    },

    //取消
    cancel() {
      this.$router.push({ path: 'article-list' })
    },

    /**
     * 打开添加标签dialog
     */
    openTagDialog() {
      this.tagDialog = true;
    },

    /**
     * 关闭标签dialog
     */
    closeTagDialog() {
      this.tagDialog = false;
    },

    /**
     * 添加标签
     */
    addTag(value) {
      if (this.articleForm.tagVOList ? this.articleForm.tagVOList.length >= 5 : false) {
        this.$message.error("标签数量不能超过5个！")
        return;
      }
      this.articleForm.tagVOList.push(value);
    },

    /**
     * 删除标签
     */
    closeTag(tagId) {
      this.articleForm.tagVOList.splice(this.articleForm.tagVOList.indexOf(tagId), 1);
    },

    /**
     * 根据id显示文章内容（修改）
     */
    loadArticleById() {
      let url = '/articles/info/';
      this.axios.get(url + this.articleId).then(response => {
        if (response.data.code === 20000) {
          this.articleForm = response.data.data;
        }
      })
    },

    /*
    查询文章类别列表
    */
    selectCategoryList() {
      let url = '/category/list';
      this.axios.get(url).then((response) => {
        if (response.data.code === 20000) {
          this.categoryList = response.data.data.pagingList;
        }
      })
    },

    /*
    查询文章标签列表
     */
    selectTagList() {
      let url = '/tag/list';
      this.axios.get(url).then((response) => {
        if (response.data.code === 20000) {
          this.tagList = response.data.data.pagingList;
        }
      })
    },


    /**
     * 提交新增表单
     * @param formName
     */
    uaArticles(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          let url = '/articles/';
          let data = this.articleForm;
          console.log("提交数据：", data)
          this.axios.post(url + (this.articleForm.id ? 'update' : 'add'), data).then((response) => {
            if (response.data.code === 20000) {
              this.$message({
                showClose: true,
                message: '操作成功！',
                type: 'success',
                onClose: () => {
                  this.$router.push({ path: 'article-list' })
                }
              });
            }
          })
        } else {
          alert('请完整填写表单!');
          return false;
        }
      })
    },


  },

  beforeDestroy() {
    const editor = this.editor
    if (editor == null) return
    editor.destroy() // 组件销毁时，及时销毁编辑器
  },

  created() {
    this.articleId = this.$route.query.articleId;
    if (this.articleId !== undefined) {
      this.loadArticleById();
    }
    this.selectCategoryList();
    this.selectTagList()
  }
}
</script>

<style scoped>
.box-card {
  background: #f8f7f5;
}

.el-input {
  width: 400px;
}


.d1 {
  border: 1px solid #ccc;
  margin: 10px 0;
  padding-top: 20px;
  padding-left: 400px;
  background: white;
  position: relative;
  z-index: 1;
}

.but {
  padding-left: 350px;
  position: relative;
  z-index: 1;
}

.fromClass {
  margin: 10px auto;
}

#form-item-content {
  margin: 0;
}

#subButton {
  margin-top: 20px;
  margin-left: 50px;
}
</style>


<style>
/* 添加全局样式，确保编辑器全屏时正常显示 */
.w-e-full-screen-container {
  position: fixed !important;
  z-index: 99999 !important;
}

.el-form-item__content.w-e-full-screen-container {
  margin-left: 0 !important;
}
</style>